package com.higgins.eventtracking.client.finance;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.higgins.eventtracking.client.AssetTrackingService;
import com.higgins.eventtracking.client.AssetTrackingServiceAsync;
import com.higgins.eventtracking.client.SecurityAccessDeniedException;
import com.higgins.eventtracking.client.dto.AssetDTO;
import com.higgins.eventtracking.client.dto.TransactionDTO;
import com.higgins.eventtracking.client.rpc.FixedOutgoingService;
import com.higgins.eventtracking.client.rpc.FixedOutgoingServiceAsync;

public class OutstandingTransactionsTable extends GenericTable	{
	private static final Logger log = Logger.getLogger(OutstandingTransactionsTable.class.getName());
	private final FixedOutgoingServiceAsync fixedOutgoingService = GWT
			.create(FixedOutgoingService.class);
	
	public OutstandingTransactionsTable(OutstandingTransactionsColumns columns)	{
		super(columns);
		retrieveDTOs();
	}
	
	private List<List<Object>> convertDTOtoRowArray(List<OutstandingTransactionDTO> outstandingTransactionDTOs)	{
		List<List<Object>> rows = new ArrayList<List<Object>>();
		for (OutstandingTransactionDTO fixedOutgoingDTO:outstandingTransactionDTOs)	{
			List<Object> row = new ArrayList<Object>();
			row.add(fixedOutgoingDTO.getId());
			row.add(fixedOutgoingDTO.getTimestamp());
			row.add(fixedOutgoingDTO.getTransactionType());
			row.add(fixedOutgoingDTO.getAmount());
			row.add(fixedOutgoingDTO.getDescription());
			row.add(fixedOutgoingDTO.getTotal());
			row.add(null);
			rows.add(row);
		}
		return rows;
	}
	
	public void updateItemCell(int row)	{
		OutstandingTransactionDTO outstandingTransactionDTO = new OutstandingTransactionDTO();
		outstandingTransactionDTO.setId(getId(row));
        outstandingTransactionDTO.setTimestamp(getDate(row, 1));
        outstandingTransactionDTO.setTransactionType(getText(row, 2));
		outstandingTransactionDTO.setAmount(getDouble(row, 3));
		outstandingTransactionDTO.setDescription(getText(row, 4));
		outstandingTransactionDTO.setTotal(getDouble(row, 5));
		updateRow(outstandingTransactionDTO);
	}
	
	protected void retrieveDTOs()	{
		try {
			fixedOutgoingService.retrieveOutstandingTransactions(new AsyncCallback<List<OutstandingTransactionDTO>>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(List<OutstandingTransactionDTO> result) {
						loadData(convertDTOtoRowArray(result));
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 
	}	
	private void updateRow(OutstandingTransactionDTO outstandingTransactionDTO)	{
		System.out.println("updating fixedOutgoingDTO " + outstandingTransactionDTO.getId());
		try {
			fixedOutgoingService.updateOutstandingTransaction(outstandingTransactionDTO, new AsyncCallback<String>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						setRowIdAfterUpdate(result);
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 		
	}
	
	protected void addObject(int row, int column, Object object)	{
		ensureRowAvailable(row);
		GenericColumn genericColumn = genericColumns.getColumn(column);
		if (column==6)	{
			addButton(row, column, object, genericColumn);
		}
	}	
	
	public void addButton(int row, int column, Object object, GenericColumn genericColumn)	{
		Button newButton = new Button("Execute");
		setWidget(row, column, newButton);
		getCellFormatter().addStyleName(row, column, "FlexTable-normCell");
		newButton.addClickHandler(new ClickHandler(){

			@Override
			public void onClick(ClickEvent event) {
				Cell cell = getCellForEvent(event);
				final int row = cell.getRowIndex();
				executeOutstandingTransaction(row);
			}});
	}
	public void executeOutstandingTransaction(int row)	{
		OutstandingTransactionDTO dto = new OutstandingTransactionDTO();
		dto.setId(getId(row));
        dto.setTimestamp(getDate(row, 1));
		dto.setTransactionType(getText(row, 2));
		dto.setAmount(getDouble(row, 3));
		dto.setDescription(getText(row, 4));
		executeOutstandingTransaction(dto);
	}


	private void executeOutstandingTransaction(OutstandingTransactionDTO dto)	{
		try {
			fixedOutgoingService.executeOutstandingTransaction(dto, new AsyncCallback<String>()	{
				@Override
				public void onFailure(Throwable caught) {
					log.info("OutstandingTransactionTable.executeOutstandingTransaction(): " + caught.toString());
				}

				@Override
				public void onSuccess(String result) {
					refresh();					
				}
			});
		} catch (Exception e)	{
			log.info("OutstandingTransactionTable.executeOutstandingTransaction: " + e.toString());
		}
	}
	protected void deleteRow(Long id)	{
		try {
			fixedOutgoingService.deleteOutstandingTransaction(id, new AsyncCallback<String>()	{
				@Override
				public void onFailure(Throwable caught) {
					log.info("OutstandingTransactionTable.deleteOutstandingTransaction(): " + caught.toString());
				}

				@Override
				public void onSuccess(String result) {
					refresh();					
				}
			});
		} catch (Exception e)	{
			log.info("OutstandingTransactionTable.deleteOutstandingTransaction: " + e.toString());
		}
	}

}
